package com.github.prontera.common.filter;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.github.prontera.StatusCode;
import com.github.prontera.common.auth0.jwt.TokenGenerator;
import com.github.prontera.common.auth0.jwt.interfaces.Claim;
import com.github.prontera.model.response.ErrorEntity;
import com.github.prontera.util.CookieManager;
import com.github.prontera.util.ServletUtil;

public class PermissionAnnotationInterceptor extends HandlerInterceptorAdapter {

	private final Pattern allowedMethods = Pattern.compile("^(POST)$");

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		if (handler instanceof HandlerMethod) {
			String uri = request.getServletPath();
			if (uri.equals("/v2/api-docs") || uri.startsWith("/swagger-resources")) {
				return true;
			}
			HandlerMethod methodHandler = (HandlerMethod) handler;
			String token = request.getHeader(MagicConstants.AUTH_TOKEN);
			if (StringUtils.isEmpty(token)) {
				token = request.getParameter(MagicConstants.AUTH_TOKEN);
			}
			if (StringUtils.isEmpty(token)) {
				token = new CookieManager(request, null).getCookie(MagicConstants.AUTH_TOKEN);
			}
			// 登录判断
			IgnoreAuth annotation = methodHandler.getMethodAnnotation(IgnoreAuth.class);
			// 如果有@IgnoreAuth注解，则不验证token
			if (annotation == null && (StringUtils.isEmpty(token))) {
				writeMessage(request, response);
				return false;
			}
			Map<String, Claim> datas = null;
			if (StringUtils.isNotEmpty(token)) {
				try {
					datas = TokenGenerator.getClaims(token); // 权限资源信息
				} catch (Exception e) {
					e.printStackTrace();
					ServletUtil.writeJson(new ErrorEntity(StatusCode.TOKEN_EXPIRED), response);// token过期
					return false;
				}
//				String userId = datas.get(MagicConstants.SESSION_USER_ID).asString();
//				if (annotation != null && (StringUtils.isEmpty(userId))) {
//					writeMessage(request, response);
//					return false;
//				}
			}
			// 有无权限访问链接
			MagicPermission magicPermission = methodHandler.getMethodAnnotation(MagicPermission.class);
			if (null != magicPermission) {
				List<String> resources = datas.get(MagicConstants.SESSION_USER_PERMISSIONS).asList(String.class);
				if (StringUtils.isEmpty(token)) {
					writeMessage(request, response);
					return false;
				}
				// 检查是否有权限访问
				boolean hasPermission = false;
				Iterator<String> iterator = resources.iterator();
				while (iterator.hasNext()) {
					String resource = iterator.next();
					if (("/" + resource).equals(uri)) { // 根据请求链接判断
						hasPermission = true;
					}
				}
				if (!hasPermission) {
					writeMessage(request, response);
					return false;
				}
			}
		}
		return true;
	}

	private void writeMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
		if (allowedMethods.matcher(request.getMethod().toUpperCase()).matches()) {
			response.setHeader("sessionstatus", "timeout");
			ServletUtil.writeJson(new ErrorEntity(StatusCode.INVALID_ACCESS), response);
		} else {
			response.sendRedirect(request.getContextPath() + "/login");
		}
	}

}
